#include "Buffer.h"
#include <stdlib.h>
#include <string.h>
#include <sys/uio.h>
#include <sys/socket.h>
#include <unistd.h>
#include <stdio.h>
Buffer::Buffer(int size)
{
    m_data = (char*)malloc(size);
    bzero(m_data, size);
}

Buffer::~Buffer() {
    if(m_data) {
        free(m_data);
    }
}

void Buffer::extendRoom(int size) {
    if(writeableSize() > size) {
        return;
    } else if(m_readPos + writeableSize() >= size) {
        int readable = readablesize();
        memcpy(m_data, m_data + m_readPos, readable);
        m_readPos = 0;
        m_writePos = readable;
    } else {
        void * temp = realloc(m_data, m_capacity + size);
        if(!temp) {
            return;
        }

        memset((char*)temp + m_capacity, 0, size);

        m_data = static_cast<char*>(temp);

        m_capacity += size;
    }
}

int Buffer::appendString(const char* data, int size) {
    if(!data || size <= 0) {
        return -1;
    }

    extendRoom(size);

    memcpy(m_data + m_writePos, data, size);

    m_writePos += size;

    return 0;
}



int Buffer::appendString(const char* data) {
    int size = strlen(data);
    return appendString(data, size);
}

int Buffer::appendString(const string data){
    return appendString(data.data());
}

int Buffer::socketRead(int fd) {
    struct iovec vec[2];
    int writeable = writeableSize();
    vec[0].iov_base = m_data + m_writePos;
    vec[0].iov_len = writeable;

    char* tmpbuf = (char*)malloc(40960);
    vec[1].iov_base = tmpbuf;
    vec[1].iov_len = 40960;

    int result = readv(fd, vec, 2);
   if(-1 == result) {
       return -1;
   } else if(result <= writeable) {
       m_writePos += result;
   } else {
        m_writePos = m_capacity;
        appendString(tmpbuf, result - writeable);
   }
   free(tmpbuf);
   return result;
}

char* Buffer::findCRLF() {
    char * ptr = (char*)memmem(m_data+m_readPos, readablesize(), "\r\n", 2);
    return ptr;
}

int Buffer::sendData(int socket) {
    int readable = readablesize();
    if(readable > 0) {
        int count = send(socket, m_data + m_readPos, readable, MSG_NOSIGNAL);
        if(count > 0) {
            m_readPos += count;
            usleep(1);
        }
        return count;
    }
    return 0;
}


